﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Web;
using Birkelund.QueryStrings.Internals;

namespace Birkelund.QueryStrings.Tokens
{
    /// <summary>
    /// Class to provide querystring tokens of a collection of strings
    /// </summary>
    // This class is kept internal as it only exposes implementation which should be used internally
    internal class StringsToken : QueryStringTokenBase<ICollection<string>>, IRenderIfNullOrEmptyValue
    {
        /// <summary>
        /// Gets or sets the char used to seperate strings
        /// </summary>
        public char Seperator { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [remove empty values].
        /// </summary>
        /// <value><c>true</c> if [remove empty values]; otherwise, <c>false</c>.</value>
        public bool RemoveEmptyValues { get; set; }

        /// <summary>
        /// Gets or sets the value indicating whether to render the token which value is empty
        /// </summary>
        /// <value>
        /// <c>true</c> or <c>false</c>.
        /// </value>
        public virtual bool RenderIfEmptyValue { get; set; }

        public StringsToken(string keyName)
            : this(keyName, ';')
        {
        }

        public StringsToken(string keyName, char seperator)
            : base(keyName)
        {
            ArgumentValidation.ThrowIfEqual(seperator.ToString(), "?", "? is not allowed as selerator");
            ArgumentValidation.ThrowIfEqual(seperator.ToString(), "&", "& is not allowed as selerator");

            Seperator = seperator;
        }

        protected override ICollection<string> OnParseFromString(string attemptedValue)
        {
            Collection<string> values = new Collection<string>();
            if (!string.IsNullOrEmpty(attemptedValue))
            {
                attemptedValue = HttpUtility.HtmlDecode(attemptedValue);
                StringSplitOptions options = RemoveEmptyValues ? StringSplitOptions.RemoveEmptyEntries : StringSplitOptions.None;
                string[] splittedValues = attemptedValue.Split(Seperator.ToString().ToCharArray(), options);
                Array.ForEach(splittedValues, values.Add);
            }
            return values;
        }

        protected override string OnRenderTokenValue(ICollection<string> value)
        {
            StringBuilder sb = new StringBuilder();
            foreach (string item in value)
            {
                sb.Append(HttpUtility.HtmlDecode(item));
                sb.Append(Seperator);
            }
            return sb.ToString().Trim(Seperator);
        }
    }
}
